package cn.jh.common.pay.jdpush;

import cn.jpush.api.JPushClient;
import cn.jpush.api.common.DeviceType;
import cn.jpush.api.common.TimeUnit;
import cn.jpush.api.common.resp.APIConnectionException;
import cn.jpush.api.common.resp.APIRequestException;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.audience.AudienceTarget;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import cn.jpush.api.push.model.notification.WinphoneNotification;
import cn.jpush.api.report.ReceivedsResult;
import cn.jpush.api.report.ReceivedsResult.Received;
import cn.jpush.api.report.UsersResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;


public class Jdpush {
    protected static final Logger log = LoggerFactory.getLogger(Jdpush.class);


    /**
     * 推送通知接口
     *
     * @param alias   别名
     * @param tags    tag数组
     * @param title   推送标题
     * @param btype   推送类型
     * @param content 推送内容
     */
    public static void sendPushNotice(String alias, String[] tags, String title, String btype, String content,String APPKEY,String MASTERSECRET) {
        PushPayload payload = null;
        // 生成推送的内容，这里我们先测试全部推送
        // 通知提示信息
        if (content != null) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("btype", btype);
            // 根据别名推送
            if (alias != null && tags == null) {
                payload = buldPushObject_all_all_alias(alias, title, content, map);
            } else if (alias == null && tags != null) { // 根据tag[]推送
                payload = buldPushObject_all_all_tag(tags, title, content, map);
            } else if (alias != null) { // 别名和tags[] 推送通知
                payload = buldPushObject_all_all_aliasAndTag(alias, tags, title, content, map);
            } else {
                payload = buldPushObject_all_all(title, content, map);
            }
        } else {
            log.info("No notification - " + content);
        }
        try {
            JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
            PushResult result = jpushClient.sendPush(payload);
        } catch (APIConnectionException e) {
            log.error("Connection error. Should retry later. ", e);
        } catch (APIRequestException e) {
            log.error("Error response from JPush server. Should review and fix it. ", e);
        }
    }

    public static void sendPushNotice(String alias, String title, String btype, String content,String APPKEY,String MASTERSECRET) {
        PushPayload payload = null;
        // 生成推送的内容，这里我们先测试全部推送  
        // 通知提示信息  
        if (content != null) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("btype", btype);
            // 根据别名推送  
            payload = buldPushObject_all_all_alias(alias, title, content, map);
        } else {
            log.info("No notification - " + content);
        }
        try {
            JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
            PushResult result = jpushClient.sendPush(payload);
        } catch (APIConnectionException e) {
            log.error("Connection error. Should retry later. ", e);
        } catch (APIRequestException e) {
            log.error("Error response from JPush server. Should review and fix it. ", e);
        }
    }
    /**
     * 根据别名推送消息
     * @param APPKEY
     * @param MASTERSECRET
     * @param alias
     * @param title
     * @param map
     * @param content
     */
    public static void sendPushNotice(String alias, String title, Map map, String content,String APPKEY, String MASTERSECRET) {
        PushPayload payload = null;
        JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
        PushResult result = new PushResult();
        // 生成推送的内容，这里我们先测试全部推送
        // 通知提示信息
        log.info("=====进入sendPushNotice发送推送通知接口");
        if (content != null) {
            // 根据别名推送
            //payload = Jdpush.buldPushObject_android_all("实名认证", "实名认证正在审核中。。。。。", map);
            payload = buldPushObject_all_all_alias(alias, title, content, map);
        } else {
            log.info("No notification - " + content);
        }
        try {
            result = jpushClient.sendPush(payload);
            log.info("=====resultmsg_id:" + result.msg_id);
            log.info("Got result - " + result);
        } catch (APIConnectionException e) {
            log.error("Connection error. Should retry later. 推送异常");
        } catch (APIRequestException e) {
            log.error("Error response from JPush server. Should review and fix it. ======异常：" + e);
        }catch (Exception e){
            log.error(" ======异常：" + e);
        }
    }
    /**
     * 根据别名和注册ID推送消息
     * @param APPKEY key值
     * @param MASTERSECRET 密钥
     * @param deviceId 注册id
     * @param alias 别名
     * @param title
     * @param map
     * @param content
     */
    public static void sendPushNotice(String source,String deviceId,String alias, String title, Map map, String content,String APPKEY, String MASTERSECRET) {
        PushPayload payload = null;
        JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
        PushResult result = new PushResult();
        // 生成推送的内容，这里我们先测试全部推送
        // 通知提示信息
        log.info("=====进入sendPushNotice发送推送通知接口");
        if (content != null) {
            // 根据别名推送
            //payload = Jdpush.buldPushObject_android_all("实名认证", "实名认证正在审核中。。。。。", map);
            payload = buldPushObject_all_all_alias(source,deviceId,alias, title, content, map);
        } else {
            log.info("No notification - " + content);
        }
        try {
            result = jpushClient.sendPush(payload);
            log.info("=====resultmsg_id:" + result.msg_id);
            log.info("Got result - " + result);
        } catch (APIConnectionException e) {
            log.error("Connection error. Should retry later. 推送异常");
        } catch (APIRequestException e) {
            log.error("Error response from JPush server. Should review and fix it. ======异常：" + e);
        }catch (Exception e){
            log.error(" ======异常：" + e);
        }
    }

    public static void sendPushNoticeAll( String title, Map map, String content,String APPKEY, String MASTERSECRET) {
        PushPayload payload = null;
        JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
        // 生成推送的内容，这里我们先测试全部推送  
        // 通知提示信息  
        if (content != null) {
            // 根据别名推送  
            payload = buldPushObject_all_all(title, content, map);
        } else {
            log.info("No notification - " + content);
        }
        try {
            PushResult result = jpushClient.sendPush(payload);
            log.info(result.msg_id + "................................");
        } catch (APIConnectionException e) {
            log.error("Connection error. Should retry later. ", e);
        } catch (APIRequestException e) {
            log.error("Error response from JPush server. Should review and fix it. ", e);
        }
    }

    public static void sendPushNoticeAndroid(String title, Map map, String content,String APPKEY, String MASTERSECRET) {
        PushPayload payload = null;
        JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
        // 生成推送的内容，这里我们先测试全部推送  
        // 通知提示信息  
        if (content != null) {
            // 根据别名推送  
            payload = buldPushObject_android_all(title, content, map);
        } else {
            log.info("No notification - " + content);
        }
        try {
            PushResult result = jpushClient.sendPush(payload);
        } catch (APIConnectionException e) {
            log.error("Connection error. Should retry later. ", e);
        } catch (APIRequestException e) {
            log.error("Error response from JPush server. Should review and fix it. ", e);
        }
    }

    public static void jfb_sendPushNotice(String alias, String title, Map map, String content, String APPKEY, String MASTERSECRET) {
        PushPayload payload = null;
        // 生成推送的内容，这里我们先测试全部推送
        // 通知提示信息
        if (content != null) {
            // 根据别名推送
            payload = buldPushObject_all_all_alias(alias, title, content, map);
        } else {
            log.info("No notification - " + content);
        }
        try {
            JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
            PushResult result = jpushClient.sendPush(payload);
            log.info("push notice result: {}", result);
        } catch (APIConnectionException ex) {
            log.error("Connection error. Should retry later. ", ex);
        } catch (APIRequestException ex) {
            log.error("Error response from JPush server. Should review and fix it. ", ex);
        }
    }

    /**
     * 推送自定义消息接口.根据别名修改标签（tag）
     *
     * @param alias   别名
     * @param content 推送内容
     */
    public static void sendPushMessage(String alias, String content, String APPKEY, String MASTERSECRET) {
        PushPayload payload = null;
        // For push, all you need do is to build PushPayload object.  
        // PushPayload payload = buildPushObject_all_all_alert();  
        // 判断用户别名和tag不为空的情况下才推送修改标签（tag）  
        if (content != null && alias != null) {
            payload = PushPayload.newBuilder()
                    .setAudience(Audience.alias(alias))
                    .setPlatform(Platform.all())
                    .setMessage(Message.content(content)).build();
        } else {
            log.info("No notification - " + content);
        }
        try {
            JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
            PushResult result = jpushClient.sendPush(payload);
            log.info("Got result - " + result);
        } catch (APIConnectionException e) {
            log.error("Connection error. Should retry later. ", e);
        } catch (APIRequestException e) {
            log.error("Error response from JPush server. Should review and fix it. ", e);
        }
    }

    /**
     * 查询记录推送成功条数
     */
    public static void countPush(String mid, String APPKEY, String MASTERSECRET) {
        PushPayload payload = null;
        try {
            JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
            ReceivedsResult result = jpushClient.getReportReceiveds(mid);
            Received received = result.received_list.get(0);
            log.info("android_received:" + received.android_received
                    + "\nios:" + received.ios_apns_sent);
            log.debug("Got result - " + result);
        } catch (APIConnectionException e) {
            // Connection error, should retry later  
            log.error("Connection error, should retry later", e);
        } catch (APIRequestException e) {
            // Should review the error, and fix the request  
            log.error("Should review the error, and fix the request", e);
            log.info("HTTP Status: " + e.getStatus());
            log.info("Error Code: " + e.getErrorCode());
            log.info("Error Message: " + e.getErrorMessage());
        }
    }

    /**
     * 统计用户数据。需要vip用户才能访问
     */
    public static void getReportUser(String APPKEY, String MASTERSECRET) {
        PushPayload payload = null;
        try {
            JPushClient jpushClient = new JPushClient(MASTERSECRET, APPKEY);
            UsersResult result = jpushClient.getReportUsers(TimeUnit.DAY, "2015-04-28", 8);
            // Received received =result  
            // System.out.println("android_received:"+received.android_received+"\nios:"+received.ios_apns_sent);  
            log.debug("Got result - " + result);
        } catch (APIConnectionException e) {
            // Connection error, should retry later  
            log.error("Connection error, should retry later", e);
        } catch (APIRequestException e) {
            // Should review the error, and fix the request  
            log.error("Should review the error, and fix the request", e);
            log.info("HTTP Status: " + e.getStatus());
            log.info("Error Code: " + e.getErrorCode());
            log.info("Error Message: " + e.getErrorMessage());
        }
    }

    /**
     * 根据别名通知推送
     */
    public static PushPayload buldPushObject_all_all_alias(String alias, String title, String content, Map<String, String> map) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.all())
                .setOptions(Options.newBuilder().setApnsProduction(true).build())
                .setAudience(Audience.alias(alias))
                .setNotification(
                        Notification
                                .newBuilder()
                                .addPlatformNotification(
                                        IosNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .addPlatformNotification(
                                        AndroidNotification.newBuilder()
                                                .setAlert(content)
                                                .setTitle(title).addExtras(map)
                                                .build())
                                .addPlatformNotification(
                                        WinphoneNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .build()).build();
    }

    /**
     * 根据tag通知推送
     */
    public static PushPayload buldPushObject_all_all_tag(String[] tags, String title, String content, Map<String, String> map) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.tag(tags))
                .setNotification(
                        Notification
                                .newBuilder()
                                .addPlatformNotification(
                                        IosNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .addPlatformNotification(
                                        AndroidNotification.newBuilder()
                                                .setAlert(content)
                                                .setTitle(title).addExtras(map)
                                                .build())
                                .addPlatformNotification(
                                        WinphoneNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .build()).build();
    }

    /**
     * 根据tag通知推送
     */
    public static PushPayload buldPushObject_all_all_aliasAndTag(String alias, String[] tags, String title, String content, Map<String, String> map) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.alias(alias))
                .setAudience(Audience.tag(tags))
                .setNotification(
                        Notification
                                .newBuilder()
                                .addPlatformNotification(
                                        IosNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .addPlatformNotification(
                                        AndroidNotification.newBuilder()
                                                .setAlert(content)
                                                .setTitle(title).addExtras(map)
                                                .build())
                                .addPlatformNotification(
                                        WinphoneNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .build()).build();
    }

    /**
     * 根据通知推送
     */
    public static PushPayload buldPushObject_all_all(String title, String content, Map<String, String> map) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.all())
                .setOptions(Options.newBuilder().setApnsProduction(true).build())
                .setAudience(Audience.all())
                .setNotification(
                        Notification
                                .newBuilder()
                                .addPlatformNotification(
                                        IosNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .addPlatformNotification(
                                        AndroidNotification.newBuilder()
                                                .setAlert(content)
                                                .setTitle(title).addExtras(map)
                                                .build())
                                .addPlatformNotification(
                                        WinphoneNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .build()).build();
    }

    /**
     * 根据通知推送
     */
    public static PushPayload buldPushObject_android_all(String title, String content, Map<String, String> map) {
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.android())
                .setAudience(Audience.all())
                .setNotification(
                        Notification
                                .newBuilder()
                                .addPlatformNotification(
                                        AndroidNotification.newBuilder()
                                                .setAlert(content)
                                                .setTitle(title).addExtras(map)
                                                .build())
                                .build()).build();
    }
    /**
     * 根据别名和设备id通知推送
     */
    public static PushPayload buldPushObject_all_all_alias(String source,String devId,String alias, String title, String content, Map<String, String> map) {
        DeviceType deviceType = null;
        if (StringUtils.isNotBlank(source)){
            if(source.equals("android")){
                deviceType = DeviceType.Android;
            }else if(source.equals("ios")){
                deviceType = DeviceType.IOS;
            }else if(source.equals("winphone")){
                deviceType = DeviceType.WinPhone;
            }
        }
        return PushPayload
                .newBuilder()
                .setPlatform(Platform.newBuilder().addDeviceType(deviceType).build())
                .setOptions(Options.newBuilder().setApnsProduction(true).build())
                //.setAudience(Audience.alias(alias))
                .setAudience(Audience.newBuilder()
                        .addAudienceTarget(AudienceTarget.alias(alias))
                        .addAudienceTarget(AudienceTarget.registrationId(devId))
                        .build())
                .setNotification(
                        Notification
                                .newBuilder()
                                .addPlatformNotification(
                                        IosNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .addPlatformNotification(
                                        AndroidNotification.newBuilder()
                                                .setAlert(content)
                                                .setTitle(title).addExtras(map)
                                                .build())
                                .addPlatformNotification(
                                        WinphoneNotification.newBuilder()
                                                .setAlert(content)
                                                .addExtras(map).build())
                                .build()).build();
    }

}